package android.moodle;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.view.Display;
import android.view.View;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

/**
 * Created by IntelliJ IDEA.
 * User: akuryou
 * Date: 4/10/11
 * Time: 5:51 PM
 * To change this template use File | Settings | File Templates.
 */
public class GameBoard implements GLSurfaceView.Renderer
{
    private float boardWidth = 0;
    private float boardHeight = 0;
    private int boardsize;
    private float width;
    private float height;
    private final int _LINE_WIDTH = 3;
    private boolean touched = false;

    float[] points = new float[]{};
    float[] square = new float[8];
    float[] cross = new float[8];
    float[] triangle = new float[6];
    float[] diamond = new float[8];
    float[] star = new float[10];

    FloatBuffer pointB;
    FloatBuffer squareB;
    FloatBuffer crossB;
    FloatBuffer triangleB;
    FloatBuffer diamondB;
    FloatBuffer starB;


    public GameBoard(Context context, float width, float height)
    {
        width = this.width;
        height = this.height;
    }

    public void onSurfaceCreated( GL10 gl, EGLConfig eglConfig )
    {
        gl.glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
        gl.glMatrixMode( GL10.GL_PROJECTION );
        gl.glLoadIdentity();
        gl.glClear( GL10.GL_COLOR_BUFFER_BIT );
        gl.glOrthof( 0.0f, width, 0.0f, height, -1.0f, 1.0f );
        gl.glMatrixMode( GL10.GL_MODELVIEW );
        gl.glLoadIdentity();
    }

    public void onSurfaceChanged( GL10 gl, int w, int h )
    {
        gl.glViewport( 0, 0, w, h );
        gl.glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
        gl.glMatrixMode( GL10.GL_PROJECTION );
        gl.glLoadIdentity();
        gl.glClear( GL10.GL_COLOR_BUFFER_BIT );
        gl.glOrthof( 0.0f, w, 0.0f, h, -1.0f, 1.0f );
        gl.glMatrixMode( GL10.GL_MODELVIEW );
        gl.glLoadIdentity();

        boardWidth = w;
        boardHeight = h;
        points = frame(w, h, 5);
        pointB = makeFloatBuffer(points);
    }


    public void onDrawFrame( GL10 gl )
    {
        gl.glClear( GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT );
        gl.glMatrixMode( GL10.GL_MODELVIEW );
        gl.glLoadIdentity();

        gl.glColor4f( 0.75f, 0.20f, 0.64f, 1.0f );
        gl.glLineWidth( _LINE_WIDTH );

        gl.glVertexPointer( 2, GL10.GL_FLOAT, 0, pointB );
        gl.glEnableClientState( GL10.GL_VERTEX_ARRAY );
        gl.glDrawArrays( GL10.GL_LINES, 0, points.length/2 );

        if( touched )
        {
            //gl.glColor4f( 1, 0, 0, 1 );
            //draw( gl );
            gl.glColor4f( 1, 1, 0, 1 );
            //drawCross( gl );
            //drawTriangle( gl );
            //drawDiamond( gl );
            gl.glLineWidth(1);
            drawStar( gl );
        }
        gl.glDisable( GL10.GL_CULL_FACE);
    }

    public void draw( GL10 gl )
    {
        gl.glVertexPointer( 2, GL10.GL_FLOAT, 0, squareB );
        gl.glEnableClientState( GL10.GL_VERTEX_ARRAY );
        gl.glDrawArrays( GL10.GL_TRIANGLES,0, square.length/2 );
    }

    public void drawCross( GL10 gl )
    {
        gl.glVertexPointer( 2, GL10.GL_FLOAT, 0, crossB );
        gl.glEnableClientState( GL10.GL_VERTEX_ARRAY );
        gl.glDrawArrays( GL10.GL_LINES, 0, cross.length/2 );
    }

    public void drawTriangle( GL10 gl )
    {
        gl.glVertexPointer( 2, GL10.GL_FLOAT, 0, triangleB );
        gl.glEnableClientState( GL10.GL_VERTEX_ARRAY );
        gl.glDrawArrays( GL10.GL_LINE_LOOP, 0, triangle.length/2 );
    }

    public void drawDiamond( GL10 gl )
    {
        gl.glVertexPointer( 2, GL10.GL_FLOAT, 0, diamondB );
        gl.glEnableClientState( GL10.GL_VERTEX_ARRAY );
        gl.glDrawArrays( GL10.GL_LINE_LOOP, 0, diamond.length/2 );
    }

    public void drawStar( GL10 gl)
    {
        gl.glVertexPointer( 2, GL10.GL_FLOAT, 0, starB );
        gl.glEnableClientState( GL10.GL_VERTEX_ARRAY );
        gl.glDrawArrays( GL10.GL_LINE_LOOP, 0, star.length/2 );
    }

    /**
     * Takes width and height from the screen, and splits into a playing field with nxn matrix.
     * @param width
     * @param height
     * @param matrix
     * @return float array of points
     */

    public float[] frame( int width, int height, int matrix )
    {
        float[] vertical;
        float[] horizontal;
        float[] points;

        if(matrix == 4) { matrix += 3; }        //7x7 matrix
        if(matrix == 5) { matrix = 2*matrix; }  //10x10 matrix

        boardsize = matrix;
        int length = ((matrix-1)*2)*2; // Calculates the amount of points it takes to draw the board with x and y coordinates

        vertical = new float[length];
        horizontal = new float[length];
        points = new float[2*length];

        for( int i = 0; i < length; i += 4 )
        {
            int mult = (i/4)+1;
            vertical[i] = mult*(width/matrix);          // x-point
            vertical[i+1] = height;                     // y-point
            vertical[i+2] = vertical[i];                // x-point
            vertical[i+3] = 0;                          // y-point
            horizontal[i] = 0;                          // x-point
            horizontal[i+1] = mult*(height/matrix);     // y-point
            horizontal[i+2] = width;                    // x-point
            horizontal[i+3] = horizontal[i+1];          // y-point
        }
        for( int j = 0; j < points.length; ++j )
        {
            if( j < length ) /* Copies over the vertical line points into the first half of the array*/
            {
                points[j] = vertical[j];
            }
            if( j >= length ) /* Copies over the horizontal line points into the second half of the array */
            {
                points[j] = horizontal[j-length];
            }
        }
        return points;
    }


    public void checkTouch( float x, float y )
    {
        int bx =        (int) ((x/boardWidth) * boardsize); // Calculates the x-position on the board, from touching
        int by =        (int) (((boardHeight-y)/boardHeight) * boardsize); // Calculates the y-position on the board, from touch
        int bwidth =    (int) (boardWidth/boardsize);       // width of the cell
        int bheight =   (int) (boardHeight/boardsize);    // height of the cell

        //Top left
        square[0] = bx * bwidth - _LINE_WIDTH;
        square[1] = by * bheight - _LINE_WIDTH;
        // Top right
        square[2] = (bx+1) * bwidth - _LINE_WIDTH;
        square[3] = square[1];
        //Bottom right
        square[4] = square[2];
        square[5] = (by+1) * bheight - _LINE_WIDTH;
        //Bottom left
        square[6] = square[0];
        square[7] = square[5];


        //Top left
        cross[0] = bx * bwidth + _LINE_WIDTH;
        cross[1] = by * bheight + _LINE_WIDTH;
        //Bottom right
        cross[2] = (bx+1) * bwidth - _LINE_WIDTH;
        cross[3] = (by+1) * bheight - _LINE_WIDTH;
        //Top right
        cross[4] = cross[2];
        cross[5] = cross[1];
        //Bottom left
        cross[6] = cross[0];
        cross[7] = cross[3];





        //Top
        diamond[0] = bx * bwidth + bwidth/2;
        diamond[1] = (by+1) * bheight - _LINE_WIDTH;
        //Left
        diamond[2] = bx * bwidth + _LINE_WIDTH;
        diamond[3] = by * bheight + bheight/2;
        //Bottom
        diamond[4] = diamond[0];
        diamond[5] = by * bheight + _LINE_WIDTH;
        //Right
        diamond[6] = (bx+1) * bwidth - _LINE_WIDTH;
        diamond[7] = diamond[3];


        //Top
        star[0] = bx * bwidth + bwidth/2 ;
        star[1] = (by+1) * bheight - 2*_LINE_WIDTH;
        //Bottom Left
        star[2] = bx * bwidth + 2*_LINE_WIDTH;
        star[3] = by * bheight + 2*_LINE_WIDTH;
        //Right
        star[4] = (bx+1) * bwidth - _LINE_WIDTH;
        star[5] = by * bheight + (13*bheight)/22;
        //Left
        star[6] = bx * bwidth + _LINE_WIDTH;
        star[7] = star[5];
        //Bottom right
        star[8] = star[4] - _LINE_WIDTH;
        star[9] = star[3];



        squareB = makeFloatBuffer(square);
        crossB = makeFloatBuffer(cross);
        triangleB = makeFloatBuffer(triangle);
        diamondB = makeFloatBuffer(diamond);
        starB = makeFloatBuffer(star);
        touched = true;
    }

    /**
     * Helping method for making floatbuffers
     * @param arr
     * @return a floatbuffer
     */
    protected static FloatBuffer makeFloatBuffer( float[] arr )
    {
		ByteBuffer bb = ByteBuffer.allocateDirect( arr.length*4 );
		bb.order( ByteOrder.nativeOrder() );
		FloatBuffer fb = bb.asFloatBuffer();
		fb.put( arr );
		fb.position( 0 );
		return fb;
	}
}